package com.ocom.mqsubsidy.business.subsidydata;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.entity.master.EntityFileDownloadInfo;
import com.ocom.common.request.payconfig.SubsidyDataRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.RandomUtil;
import com.ocom.common.utils.excel.SXSSFWORKBookUtils;
import com.ocom.common.vo.payconfig.SubsidyDataVo;
import com.ocom.common.vo.simple.ConsumeDetailVo;
import com.ocom.mqsubsidy.config.SubsidyDataConfig;
import com.ocom.mqsubsidy.feign.AccessClientService;
import com.ocom.mqsubsidy.feign.MinioClientService;
import com.ocom.mqsubsidy.feign.PayConfigClientService;
import com.rabbitmq.client.Channel;
import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Map;


@Component
public class SubsidyDataConsumerMqListener {

	private Logger logger = LoggerFactory.getLogger(SubsidyDataConsumerMqListener.class);



	@Autowired
	private PayConfigClientService payConfigClientService;


	@Autowired
	AccessClientService accessClientService;

	@Value("${save.path}")
	String excelPath;

	@Autowired
	MinioClientService minioClientService;

	/**
	 * 把该监听命名为A监听
	 * 监听队列  远程服务支付接口发送消息  该队列会接受
	 * [message, headers, channel]
	 * @return {@link }
	 * @throws
	 */
	@RabbitListener(queues = SubsidyDataConfig.SUBSIDYDATA_QUEUE)
	public void process(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
		logger.info("补贴明细导出 消费中");
		logger.info("message【{}】", message);
		String humanMessage = new String(message.getBody(), StandardCharsets.UTF_8);
		//TODO 数据库操作样例
		logger.info("SubsidyData-start:【{}】", humanMessage);
		logger.info("System.currentTimeMillis()【{}】", System.currentTimeMillis());


		SubsidyDataRequest subsidyDataRequest = JSON.parseObject(humanMessage,SubsidyDataRequest.class);

		subsidyDataRequest.setSize(1);
		subsidyDataRequest.setPage(1);
		EntityFileDownloadInfo entityFileDownloadInfo=new EntityFileDownloadInfo();
		entityFileDownloadInfo.setId(subsidyDataRequest.getId().longValue());
		entityFileDownloadInfo.setName("导出补贴数据");

		String filePath = excelPath+ RandomUtil.getRandomString(32) +".xlsx";
		File file=new File(filePath);

		//创建一个文件
		try {
			//创建Excel文件薄
			HSSFWorkbook workbook=new HSSFWorkbook();
			//创建工作表sheeet
			workbook.createSheet();
			//判断文件或文件夹是否存在
			boolean flag = file.exists();
			if(flag)
			{
				//文件存在就要删除文件
				file.delete();
			}
			file.createNewFile();
			FileOutputStream stream= FileUtils.openOutputStream(file);
			workbook.write(stream);
			stream.close();
		}catch (Exception e){
			e.printStackTrace();
		}finally {

		}

		SXSSFWorkbook sxssfWorkbook = null;
		BufferedOutputStream outputStream = null;
		try {
			//这样表示SXSSFWorkbook只会保留100条数据在内存中，其它的数据都会写到磁盘里，这样的话占用的内存就会很少
			sxssfWorkbook = new SXSSFWorkbook(SXSSFWORKBookUtils.getXSSFWorkbook(filePath),100);
			//获取第一个Sheet页
			SXSSFSheet sheet = sxssfWorkbook.getSheetAt(0);

			Result result =payConfigClientService.subsidyData(subsidyDataRequest);

			if(result.getCode()!=200){
				throw  new RuntimeException("获取补贴列表导出- 获取异常");
			}

			ConsumeDetailVo mjRecords = JSON.parseObject(JSON.toJSONString(result.getData()),ConsumeDetailVo.class);

			//下载失败 无数据
			if(mjRecords.getTotal()<=0){
				//下载失败
				entityFileDownloadInfo.setStatus(2l);
				entityFileDownloadInfo.setRemark("无有效记录");
				accessClientService.UpdateFileStatus(entityFileDownloadInfo);

				throw new RuntimeException("无有效记录");
			}

			int a = mjRecords.getTotal();
			int b = 500;
			BigDecimal aBig = new BigDecimal(a);
			BigDecimal bBig = new BigDecimal(b);
			//向上取整
			Integer pages =   (int)Math.ceil(aBig.divide(bBig).doubleValue());

			SXSSFRow row0 = sheet.createRow(0);
			row0.createCell(0).setCellValue("编号");
			row0.createCell(1).setCellValue("员工编号");
			row0.createCell(2).setCellValue("学工号");
			row0.createCell(3).setCellValue("姓名");
			row0.createCell(4).setCellValue("部门编号");
			row0.createCell(5).setCellValue("消费账户类型");
			row0.createCell(6).setCellValue("补贴金额");
			row0.createCell(7).setCellValue("发放状态(1：未发放；4：已发放；5：停止发放；-1：发放失败)");
			row0.createCell(8).setCellValue("实际发放");
			row0.createCell(9).setCellValue("清补贴");
			row0.createCell(10).setCellValue("发放时间");

			for (int i = 0; i < pages; i++) {
				subsidyDataRequest.setPage(i+1);
				subsidyDataRequest.setSize(500);
				Result result1 =payConfigClientService.subsidyData(subsidyDataRequest);

				ConsumeDetailVo mjRecords1 = JSON.parseObject(JSON.toJSONString(result1.getData()),ConsumeDetailVo.class);

				int  z =0;
				for (Object o:mjRecords1.getList()){

					SubsidyDataVo subsidyDataVo= JSON.parseObject(JSON.toJSONString(o),SubsidyDataVo.class);
					z++;
					SXSSFRow row = sheet.createRow(i * 500 + z);

					row.createCell(0).setCellValue(subsidyDataVo.getId());
					row.createCell(1).setCellValue(subsidyDataVo.getPId());
					row.createCell(2).setCellValue(subsidyDataVo.getPCode());
					if (subsidyDataVo.getPName()==null){
						row.createCell(3).setCellValue("");
					}else {
						row.createCell(3).setCellValue(subsidyDataVo.getPName());
					}
					if (subsidyDataVo.getDeptId()==null){
						row.createCell(4).setCellValue(0);
					}else {
						row.createCell(4).setCellValue(subsidyDataVo.getDeptId());
					}
					if (subsidyDataVo.getAccType()==null){
						row.createCell(5).setCellValue(0);
					}else {
						row.createCell(5).setCellValue(subsidyDataVo.getAccType());
					}
					if (null != subsidyDataVo.getPlanMoney() && 0 < subsidyDataVo.getPlanMoney()) {
						row.createCell(6).setCellValue(subsidyDataVo.getPlanMoney() / 100);
					} else {
						row.createCell(6).setCellValue(subsidyDataVo.getPlanMoney() / 100);
					}

					row.createCell(7).setCellValue(subsidyDataVo.getDataStatus());
					if (null != subsidyDataVo.getCompleteMoney() && 0 < subsidyDataVo.getCompleteMoney()) {
						row.createCell(8).setCellValue(subsidyDataVo.getCompleteMoney() / 100);
					} else {
						row.createCell(8).setCellValue(subsidyDataVo.getCompleteMoney() / 100);
					}
					row.createCell(9).setCellValue(subsidyDataVo.getClearMoney() / 100

					);
					row.createCell(10).setCellValue(subsidyDataVo.getCompleteTime());
				}

			}

			outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
			sxssfWorkbook.write(outputStream);
			outputStream.flush();
			sxssfWorkbook.dispose();// 释放workbook所占用的所有windows资源
		} catch (IOException e) {
			e.printStackTrace();

			entityFileDownloadInfo.setStatus(2l);
			accessClientService.UpdateFileStatus(entityFileDownloadInfo);
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
			return;

		}finally {
			if(outputStream!=null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		File file1=new File(filePath);
		Result result3 = minioClientService.upload(file1);
		//删除本地
		file.delete();
		if(result3.getCode()!=200){
			//更改状态 失败
			entityFileDownloadInfo.setStatus(2l);
			accessClientService.UpdateFileStatus(entityFileDownloadInfo);
		}else{
			JSONObject jsonObject1 =JSON.parseObject(JSON.toJSONString( result3.getData()));
			entityFileDownloadInfo.setStatus(1l);
			entityFileDownloadInfo.setUrl(jsonObject1.getString("imageUrl"));
			accessClientService.UpdateFileStatus(entityFileDownloadInfo);
		}
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		logger.info("获取补贴列表导出-end:【{}】",humanMessage);
		logger.info("System.currentTimeMillis()【{}】",System.currentTimeMillis());
	}

	/**
	 * 把该监听命名为B监听
	 * 监听死信队列  远程服务支付接口发送消息  该队列会接受
	 * [message, headers, channel]
	 * @return {@link }
	 * @throws
	 */
	@RabbitListener(queues =  SubsidyDataConfig.SUBSIDYDATA_DIE_QUEUE)
	public void processForDie(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception {
		//死信队列放弃
		channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
		logger.info("补贴明细导出-死信队列放弃 ， 【{}】",message);
	}


}
